package com.example.bilibili.service;

import com.example.bilibili.dao.UserFollowingDao;
import com.example.bilibili.domain.FollowingGroup;
import com.example.bilibili.domain.User;
import com.example.bilibili.domain.UserFollowing;
import com.example.bilibili.domain.UserInfo;
import com.example.bilibili.domain.constant.UserConstant;
import com.example.bilibili.domain.exception.ConditionException;
import com.sun.org.apache.bcel.internal.generic.RETURN;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;

@Service
public class UserFollowingService {

    @Autowired
    private UserFollowingDao userFollowingDao;

    @Autowired
    private FollowingGroupService followingGroupService;

    @Autowired
    private UserService userService;

    /**
     * 添加用户关注
     */
    @Transactional
    public void addUserFollowings(UserFollowing userFollowing) {
        Long groupId = userFollowing.getGroupId();
        // groupId 不存在则设置为默认分组, groupId 存在则判空
        if (groupId == null) {
            FollowingGroup followingGroup = followingGroupService.getByType(UserConstant.USER_FOLLOWING_GROUP_TYPE_DEFAULT);
            userFollowing.setGroupId(followingGroup.getId());
        } else {
            FollowingGroup followingGroup = followingGroupService.getById(groupId);
            if (followingGroup == null) {
                throw new ConditionException("关注分组不存在！");
            }
        }
        // 得到该用户的关注用户id 判空
        Long followingId = userFollowing.getFollowingId();
        User user = userService.getUserById(followingId);
        if (user == null) {
            throw new ConditionException("关注的用户不存在！");
        }
        // 删除原来的用户关注分组信息，例如: A 关注了 B 设置为 悄悄关注 , 后来 A 关注了 B 设置为 特别关注
        userFollowingDao.deleteUserFollowing(userFollowing.getUserId(), followingId);
        userFollowing.setCreateTime(new Date());
        // 添加新的用户关注分组信息
        userFollowingDao.addUserFollowing(userFollowing);
    }

    /**
     * 获取用户关注列表
     * 1.获取关注列表
     * 2.根据关注用户的id查询关注用户的基本信息
     * 3.将关注用户按关注分组进行分类
     */
    public List<FollowingGroup> getUserFollowings(Long userId) {
        // 得到该用户的关注列表 list
        List<UserFollowing> list = userFollowingDao.getUserFollowings(userId);

        // 通过 Stream 处理 list 得到所有的关注id（去重） followingIdSet
        Set<Long> followingIdSet = list.stream().map(UserFollowing::getFollowingId).collect(Collectors.toSet());

        // 通过ids得到用户信息列表 userInfoList
        ArrayList<UserInfo> userInfoList = new ArrayList();
        if (followingIdSet.size() > 0) {
            userInfoList = userService.getUserInfoByUserIds(followingIdSet);
        }

        // 将查询出的用户信息插入进 list 中
        for (UserFollowing userFollowing : list) {
            for (UserInfo userInfo : userInfoList) {
                if (userFollowing.getFollowingId().equals(userInfo.getUserId())) {
                    userFollowing.setUserInfo(userInfo);
                }
            }
        }

        // 该用户的分组集合: 0特别关注 1悄悄关注 2默认分组 3用户自定义分组
        List<FollowingGroup> groupList = followingGroupService.getByUserId(userId);

        // 将所有关注的用户信息填充到'关注分组'中
        FollowingGroup allGroup = new FollowingGroup();
        allGroup.setName(UserConstant.USER_FOLLOWING_GROUP_ALL_NAME);
        allGroup.setFollowingUserInfoList(userInfoList);

        // result：将关注用户按关注分组进行分类
        List<FollowingGroup> result = new ArrayList<>();
        result.add(allGroup);

        /**
         * 遍历所有的 group {
         *    infoList 初始化
         *    遍历该用户的全部关注列表 list {
         *      判断每个关注的用户的 groupId 是否等于当前遍历的 group {
         *          将 infoList 加入分组 group 中
         *      }
         *    }
         *    将 group 加入到最后结果集 result
         *  }
         */
        for (FollowingGroup group : groupList) {
            ArrayList<UserInfo> infoList = new ArrayList<>();
            for (UserFollowing userFollowing : list) {
                if (group.getId().equals(userFollowing.getGroupId())) {
                    infoList.add(userFollowing.getUserInfo());
                }
            }
            group.setFollowingUserInfoList(infoList);
            result.add(group);
        }
        return result;
    }

    /**
     * 获取用户粉丝列表
     * 1.获取粉丝列表
     * 2.根据粉丝的用户id查询基本信息
     * 3.查询当前用户是否已经关注该粉丝
     */
    public List<UserFollowing> getUserFans(Long userId) {
        // 得到该用户的所有粉丝 fanList
        List<UserFollowing> fanList = userFollowingDao.getUserFans(userId);

        // 得到去重后的所有粉丝ID: fanIdSet
        Set<Long> fanIdSet = fanList.stream().map(UserFollowing::getUserId).collect(Collectors.toSet());

        // 通过 fanIdSet 得到粉丝信息列表 userInfoList
        List<UserInfo> userInfoList = new ArrayList<>();
        if (fanIdSet.size() > 0) {
            userInfoList = userService.getUserInfoByUserIds(fanIdSet);
        }

        // 将查询出的用户信息填充到 fanList 中
        // 初始化属性 followed 为: false (表示当前用户默认未关注该粉丝)
        for (UserFollowing fan : fanList) {
            for (UserInfo userInfo : userInfoList) {
                if (fan.getUserId().equals(userInfo.getUserId())) {
                    userInfo.setFollowed(false);
                    fan.setUserInfo(userInfo);
                }
            }
        }

        // 判断当前用户是否已经关注该粉丝
        // followed 为: true (表示当前用户也关注该粉丝, 为互关关系)
        List<UserFollowing> followingList = userFollowingDao.getUserFollowings(userId);
        for (UserFollowing fan : fanList) {
            for (UserFollowing following : followingList) {
                if (following.getFollowingId().equals(fan.getUserId())) {
                    fan.getUserInfo().setFollowed(true);
                }
            }
        }
        return fanList;
    }


    public Long addUserFollowingGroups(FollowingGroup followingGroup) {
        followingGroup.setCreateTime(new Date());
        followingGroup.setType(UserConstant.USER_FOLLOWING_GROUP_TYPE_USER);
        followingGroupService.addFollowingGroup(followingGroup);
        return followingGroup.getId();
    }

    public List<FollowingGroup> getUserFollowingGroups(Long userId) {
        return followingGroupService.getUserFollowingGroups(userId);
    }

    public List<UserInfo> checkFollowingStatus(List<UserInfo> userInfoList, Long userId) {
        List<UserFollowing> userFollowingList = userFollowingDao.getUserFollowings(userId);
        for (UserInfo userInfo : userInfoList) {
            userInfo.setFollowed(false);
            for (UserFollowing userFollowing : userFollowingList) {
                if (userFollowing.getFollowingId().equals(userInfo.getUserId())) {
                    userInfo.setFollowed(true);
                }
            }
        }
        return userInfoList;
    }
}
